package com.shihb.akka.yellochicken.client

import akka.actor.{Actor, ActorRef, ActorSelection, ActorSystem, Props}
import com.shihb.akka.yellochicken.common.{ClientMessage, ServerMessage}
import com.typesafe.config.{Config, ConfigFactory}

import scala.io.StdIn

class ClientActor(serverHost: String, serverPort: Int) extends Actor {
  // 定义一个YellowChickServer的引用这里是ActorSelection,不是ActorRef了
  var serverActorRef: ActorSelection = _

  // 在Actor中有一个PreStart方法，他会在actor运行前执行
  // 在akkaz中经常用它来初始化
  override def preStart(): Unit = {
    //akka.tcp://server@$serverHost:$serverPort/user/YellowChickServer
    // akka.tcp:协议
    // server服务器ActorSystem名
    // $serverHost 服务器host
    // $serverPort 服务器port
    // YellowChickServer 小黄鸡的AcotorRef名
    serverActorRef = context.actorSelection(s"akka.tcp://server@$serverHost:$serverPort/user/YellowChickServer")
    println("serverActorRef" + serverActorRef)
  }

  override def receive: Receive = {
    case "start" => println("客户端运行了,可以咨询问题...")
    case "exit" => {
      println("接收到退出指令,退出系统")
      context.stop(self) //停止actorRef
      context.system.terminate() //停止actorSystem
    }
    // 发送给小黄鸡客服,封装了client消息的样例类
    case msg: String => serverActorRef ! ClientMessage(msg)
    case ServerMessage(msg) => {
      println("收到小黄鸡客服的回复:"+msg)
    }
  }
}

object ClientActor extends App {
  val (host, port, serverHost, serverPort) = ("127.0.0.1", 9998, "127.0.0.1", 9999)

  val config: Config = ConfigFactory.parseString(
    s"""
       |akka.actor.provider="akka.remote.RemoteActorRefProvider"
       |akka.remote.netty.tcp.hostname=$host
       |akka.remote.netty.tcp.port=$port
       |""".stripMargin)

  val clientActorSystem: ActorSystem = ActorSystem("client", config)
  //创建客户端Actor的引用
  val clientActorRef: ActorRef = clientActorSystem.actorOf(Props(new ClientActor(serverHost, serverPort)), "clientActorRef")
  //启动
  clientActorRef ! "start"

  import util.control.Breaks._

  breakable {
    while (true) {
      println("请输入要咨询的问题(exit退出):")
      val msg: String = StdIn.readLine()
      if ("exit".equalsIgnoreCase(msg)) {
        clientActorRef ! "exit"
        break()
      }
      clientActorRef ! msg
    }
  }


}
